/**
 * @author 0283000115
 * @date 2018年3月3日-下午2:32:37
 */
package com.zte.claa.inficombo.csa.app.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.zte.claa.inficombo.csa.app.controller.ret.ApiResult;
import com.zte.claa.inficombo.csa.app.controller.ret.AppStatus;
import com.zte.claa.inficombo.csa.app.controller.ret.BcastQueQryAck;
import com.zte.claa.inficombo.csa.app.controller.ret.DevBuffQryAck;
import com.zte.claa.inficombo.csa.app.controller.ret.DevClazzQryAck;
import com.zte.claa.inficombo.csa.app.controller.ret.DevDataQryAck;
import com.zte.claa.inficombo.csa.app.controller.ret.DevStateQryAck;
import com.zte.claa.inficombo.csa.app.controller.ret.MspAck;
import com.zte.claa.inficombo.csa.app.model.app.AppTarget;
import com.zte.claa.inficombo.csa.app.model.dev.DevBase;
import com.zte.claa.inficombo.csa.app.model.dev.DevRunState;
import com.zte.claa.inficombo.csa.app.service.csa.CSAMainService;
import com.zte.claa.inficombo.csa.app.service.csa.impl.BaseCacheManager;
import com.zte.claa.inficombo.csa.app.service.persistent.CSADataPersistService;
import com.zte.claa.inficombo.csa.app.util.JsonUtils;
import com.zte.claa.inficombo.csa.app.util.XEuiUtils;

import io.swagger.annotations.ApiOperation;

/**
 * @author 0283000115
 *
 */

@RestController
@RequestMapping("/csa/api/v1") 
public class CSAApiController extends BaseController {
	// logger
	private Logger logger = LoggerFactory.getLogger(CSAApiController.class);
	
	@Autowired 
	private CSAMainService csaMainService;
	
	@Autowired 
	private CSADataPersistService persistService;
	
	@Autowired
	private BaseCacheManager cacheManager;

    /**
     * AppEUI添加
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     * HttpServletRequest request, HttpSession session
     */
	@ApiOperation(value = "AppEUI添加", notes = "")
	@RequestMapping(value={"/addappeui"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> addAppEui(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		String appAuthKey = request.getParameter("appauthkey");
		String csifIp = request.getParameter("csifip");
		String csifPort = request.getParameter("csifport");		
		appEui = (appEui == null) ? "" : appEui.trim();
		appAuthKey = (appAuthKey == null) ? "" : appAuthKey.trim();
		logger.info("addAppEui: appEui="+appEui+", appAuthKey="+appAuthKey+", csifIp="+csifIp+", csifPort="+csifPort);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		if(appAuthKey.equals("")){
			throw new Exception("AppAuthKey不能为空！");
		}
		AppTarget appTarget = new AppTarget();
		appTarget.setAppAuthKey(appAuthKey);
		appTarget.setAppEUI(appEui);
		appTarget.setCsifIpAddr(csifIp);
		appTarget.setCsifPort(Integer.parseInt(csifPort.trim()));
		ApiResult<String> ret = new ApiResult<String>();
		this.csaMainService.addAppEui(appEui, appTarget);
		ret.setData("");
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * AppEUI移除
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     * HttpServletRequest request, HttpSession session
     */
	@ApiOperation(value = "AppEUI移除", notes = "")
	@RequestMapping(value={"/removeappeui"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> removeAppEui(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		appEui = (appEui == null) ? "" : appEui.trim();
		logger.info("removeAppEui: appEui="+appEui);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		ApiResult<String> ret = new ApiResult<String>();
		this.csaMainService.removeAppEui(appEui);
		ret.setData("");
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * 查询AppEUI列表及到CSIF的连接状态.
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     * HttpServletRequest request, HttpSession session
     */
	@ApiOperation(value = "AppEUI查询", notes = "")
	@RequestMapping(value={"/listappeui"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> listAppEui(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		ApiResult<List<AppStatus>> ret = new ApiResult<List<AppStatus>>();
		List<String> appEuiList = this.csaMainService.getAppEuis();
		List<AppStatus> retData = new ArrayList<AppStatus>();
		if(appEuiList != null){
			for(String appEui : appEuiList){
				retData.add(this.csaMainService.getAppLinkState(appEui));
			}
		}
		ret.setData(retData);
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * CSJoin
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     * HttpServletRequest request, HttpSession session
     */
	@ApiOperation(value = "CSJoin", notes = "")
	@RequestMapping(value={"/csjoin"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> csJoin(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		appEui = (appEui == null) ? "" : appEui.trim();
		logger.info("csJoin: appEui="+appEui);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		String jsonStr = this.csaMainService.CSJoin(appEui);
		logger.info("csJoin: appEui="+appEui+", ret="+jsonStr);
		ApiResult<MspAck> ret = new ApiResult<MspAck>();		
		ret.setData(this.parseAckJson(jsonStr, "appeui"));
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * CSQuit
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     * HttpServletRequest request, HttpSession session
     */
	@ApiOperation(value = "CSQuit", notes = "")
	@RequestMapping(value={"/csquit"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> csQuit(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		appEui = (appEui == null) ? "" : appEui.trim();
		logger.info("csQuit: appEui="+appEui);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		String jsonStr = this.csaMainService.CSQuit(appEui);
		logger.info("csQuit: appEui="+appEui+", ret="+jsonStr);
		ApiResult<MspAck> ret = new ApiResult<MspAck>();		
		ret.setData(this.parseAckJson(jsonStr, "appeui"));
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * sendDevCtrlCmd
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     * SendDevCtrlCmd(String appEeui, String devEui, boolean confirm, int port, String payload)
     */
	@ApiOperation(value = "sendDevCtrlCmd", notes = "")
	@RequestMapping(value={"/senddevctrlcmd"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> sendDevCtrlCmd(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		String devEui = request.getParameter("deveui");
		String confirmStr = request.getParameter("confirm");
		String portStr = request.getParameter("port");
		String payLoad = request.getParameter("payload");		
		appEui = (appEui == null) ? "" : appEui.trim();
		logger.info("sendDevCtrlCmd: appEui="+appEui+", deveui="+devEui+", confirm="+confirmStr+", port="+portStr+", payload="+payLoad);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		if(devEui.equals("")){
			throw new Exception("DevEUI不能为空！");
		}
		// 1==confirm命令》
		boolean confirm = ("1".equals(confirmStr.trim()) || "true".equalsIgnoreCase(confirmStr.trim()));
		int port = 0;
		try{
			port = Integer.parseInt(portStr);
		}catch(Exception ignore){}
		String jsonStr = this.csaMainService.SendDevCtrlCmd(appEui, devEui, confirm, port, payLoad, null);
		logger.info("sendDevCtrlCmd: appEui="+appEui+", deveui="+devEui+", ret="+jsonStr);
		ApiResult<MspAck> ret = new ApiResult<MspAck>();		
		ret.setData(this.parseAckJson(jsonStr, "deveui"));
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * DevBuffQuery
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     */
	@ApiOperation(value = "DevBuffQuery", notes = "")
	@RequestMapping(value={"/devbuffquery"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> devBuffQuery(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		String devEui = request.getParameter("deveui");		
		appEui = (appEui == null) ? "" : appEui.trim();
		logger.info("devBuffQuery: appEui="+appEui+", deveui="+devEui);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		if(devEui.equals("")){
			throw new Exception("DevEUI不能为空！");
		}
		String jsonStr = this.csaMainService.DevBuffQuery(appEui, devEui);
		logger.info("devBuffQuery: appEui="+appEui+", deveui="+devEui+", ret="+jsonStr);
		ApiResult<DevBuffQryAck> ret = new ApiResult<DevBuffQryAck>();		
		ret.setData(this.parseBuffQryAckJson(jsonStr));
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * DevClassQuery
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     */
	@ApiOperation(value = "DevClassQuery", notes = "")
	@RequestMapping(value={"/devclassquery"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> devClassQuery(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		String devEui = request.getParameter("deveui");		
		appEui = (appEui == null) ? "" : appEui.trim();
		logger.info("devClassQuery: appEui="+appEui+", deveui="+devEui);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		if(devEui.equals("")){
			throw new Exception("DevEUI不能为空！");
		}
		String jsonStr = this.csaMainService.DevClassQuery(appEui, devEui);
		logger.info("devClassQuery: appEui="+appEui+", deveui="+devEui+", ret="+jsonStr);
		ApiResult<DevClazzQryAck> ret = new ApiResult<DevClazzQryAck>();		
		ret.setData(this.parseClassQryAckJson(jsonStr));
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * DevStateQuery
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     */
	@ApiOperation(value = "DevStateQuery", notes = "")
	@RequestMapping(value={"/devstatequery"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> devStateQuery(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		String devEui = request.getParameter("deveui");		
		appEui = (appEui == null) ? "" : appEui.trim();
		logger.info("devStateQuery: appEui="+appEui+", deveui="+devEui);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		if(devEui.equals("")){
			throw new Exception("DevEUI不能为空！");
		}
		String jsonStr = this.csaMainService.DevStateQuery(appEui, devEui);
		logger.info("devStateQuery: appEui="+appEui+", deveui="+devEui+", ret="+jsonStr);
		ApiResult<DevStateQryAck> ret = new ApiResult<DevStateQryAck>();		
		ret.setData(this.parseDevStateQryAckJson(jsonStr));
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * BcastCmd
     * 
     * @param request
     * @return 
     * @throws Exception
     * appEui, int port, int times, String devTypeId, String payload
     */
	@ApiOperation(value = "BcastCmd", notes = "")
	@RequestMapping(value={"/bcastcmd"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> sendBcastCmd(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");
		String devTypeId = request.getParameter("devTypeId");
		String timesStr = request.getParameter("times");
		String portStr = request.getParameter("port");
		String payLoad = request.getParameter("payload");		
		appEui = (appEui == null) ? "" : appEui.trim();
		timesStr = (timesStr == null || timesStr.trim().equals("")) ? "1" : timesStr.trim();
		logger.info("sendBcastCmd: appEui="+appEui+", devTypeId="+devTypeId+", timesStr="+timesStr+", port="+portStr+", payload="+payLoad);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		int times = Integer.parseInt(timesStr.trim());
		int port = 0;
		try{
			port = Integer.parseInt(portStr);
		}catch(Exception ignore){}
		String jsonStr = this.csaMainService.SendBcastCmd(appEui, port, times, devTypeId, payLoad, null);
		logger.info("sendBcastCmd: appEui="+appEui+", devTypeId="+devTypeId+", ret="+jsonStr);
		ApiResult<MspAck> ret = new ApiResult<MspAck>();		
		ret.setData(this.parseAckJson(jsonStr, "appeui"));
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * BcastQueQuery
     * 
     * @param request
     * @return 
     * @throws Exception
     * 
     */
	@ApiOperation(value = "BcastQueQuery", notes = "")
	@RequestMapping(value={"/bcastquequery"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> bcastquequery(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}	
		String appEui = request.getParameter("appeui");	
		appEui = (appEui == null) ? "" : appEui.trim();
		logger.info("bcastquequery: appEui="+appEui);
		if(appEui.equals("")){
			throw new Exception("AppEUI不能为空！");
		}
		String jsonStr = this.csaMainService.BcastQueueQuery(appEui);
		logger.info("bcastquequery: appEui="+appEui+", ret="+jsonStr);
		ApiResult<BcastQueQryAck> ret = new ApiResult<BcastQueQryAck>();		
		ret.setData(this.parseBcastQueQryAckJson(jsonStr));
		ret.setRemark("success");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * CSIF-Dev-Add命令执行.
     * addDev(String appeui, String deveui, String appkey, String clazz, int offlinetime)
     * 
     * appeui: appEUI;
     * deveui: 设备编号.
     * appkey: appeky，可选，明文.
     * clazz: 'A'|'B'|'C'
	 * offlinetime: int, 单位：分钟，0表示不设置... 
	 * 
     * @param request
     * @return 
     * @throws Exception
     */
	@ApiOperation(value = "addDev2CSIF", notes = "通过CSIF接口添加DEV（仅限于LNS系统）")
	@RequestMapping(value={"/adddev2csif"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> adddev2csif(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}			
		String devEui = request.getParameter("deveui");
		if(devEui == null || devEui.trim().equals("")){
			ret1 = new ApiResult<String>();
			ret1.setRemark("DevEUI parameter is null!");
			ret1.setResult(ApiResult.RET_FAIL);
			return ret1;
		}
		devEui = devEui.trim().toLowerCase();
		String appEui = request.getParameter("appeui");
		if(appEui == null || appEui.trim().equals("")){
			appEui = this.getAppEuiByDevEui(devEui);
		}
		if(appEui == null){
			ret1 = new ApiResult<String>();
			ret1.setRemark("Can't get AppEUI by DevEUI: "+devEui);
			ret1.setResult(ApiResult.RET_FAIL);
			return ret1;
		}
		String appkey = request.getParameter("appkey");
		String clazz = request.getParameter("clazz");
		String offlinetime = request.getParameter("offlinetime");
		int offlinetimeMinutes = 0;
		try{
			offlinetimeMinutes = Integer.parseInt(offlinetime);
		}catch(Exception ignore){}		
		logger.info("Begin to adddev2csif: appEui="+appEui+", deveui="+devEui+", appkey="+appkey+", clazz="+clazz+", offlinetime="+offlinetimeMinutes);
		String jsonStr = this.csaMainService.addDev(appEui, devEui, appkey, clazz, offlinetimeMinutes);
		logger.info("adddev2csif: appEui="+appEui+", deveui="+devEui+", ret="+jsonStr);
		ApiResult<MspAck> ret = new ApiResult<MspAck>();		
		ret.setData(this.parseAckJson(jsonStr, "deveui"));
		ret.setRemark("");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * CSIF-Dev-Del命令执行.
     * removeDev(String appeui, String deveui)
     * 
     * appeui: appEUI，可选;
     * deveui: 设备编号.
	 * 
     * @param request
     * @return 
     * @throws Exception
     */
	@ApiOperation(value = "removeDevFromCSIF", notes = "通过CSIF接口删除DEV（仅限于LNS系统）")
	@RequestMapping(value={"/removedevfromcsif"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> removedevfromcsif(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}			
		String devEui = request.getParameter("deveui");
		if(devEui == null || devEui.trim().equals("")){
			ret1 = new ApiResult<String>();
			ret1.setRemark("DevEUI parameter is null!");
			ret1.setResult(ApiResult.RET_FAIL);
			return ret1;
		}
		devEui = devEui.trim().toLowerCase();
		String appEui = request.getParameter("appeui");
		if(appEui == null || appEui.trim().equals("")){
			appEui = this.getAppEuiByDevEui(devEui);
		}
		if(appEui == null){
			ret1 = new ApiResult<String>();
			ret1.setRemark("Can't get AppEUI by DevEUI: "+devEui);
			ret1.setResult(ApiResult.RET_FAIL);
			return ret1;
		}	
		logger.info("begin to removedevfromcsif: appEui="+appEui+", deveui="+devEui);
		String jsonStr = this.csaMainService.removeDev(appEui, devEui);
		logger.info("removedevfromcsif: appEui="+appEui+", deveui="+devEui+", ret="+jsonStr);
		ApiResult<MspAck> ret = new ApiResult<MspAck>();		
		ret.setData(this.parseAckJson(jsonStr, "deveui"));
		ret.setRemark("");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * CSIF-Dev-Modify命令执行.
     * modifyDev(String appeui, String deveui, int offlinetime) 
     * 
     * appeui: appEUI;
     * deveui: 设备编号.
	 * offlinetime: int, 单位：分钟，0表示不设置... 
	 * 
     * @param request
     * @return 
     * @throws Exception
     */
	@ApiOperation(value = "modDev2CSIF", notes = "通过CSIF接口修改DEV（仅限于LNS系统）")
	@RequestMapping(value={"/moddev2csif"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> moddev2csif(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}			
		String devEui = request.getParameter("deveui");
		if(devEui == null || devEui.trim().equals("")){
			ret1 = new ApiResult<String>();
			ret1.setRemark("DevEUI parameter is null!");
			ret1.setResult(ApiResult.RET_FAIL);
			return ret1;
		}
		devEui = devEui.trim().toLowerCase();
		String appEui = request.getParameter("appeui");
		if(appEui == null || appEui.trim().equals("")){
			appEui = this.getAppEuiByDevEui(devEui);
		}
		if(appEui == null){
			ret1 = new ApiResult<String>();
			ret1.setRemark("Can't get AppEUI by DevEUI: "+devEui);
			ret1.setResult(ApiResult.RET_FAIL);
			return ret1;
		}
		String offlinetime = request.getParameter("offlinetime");
		int offlinetimeMinutes = 0;
		try{
			offlinetimeMinutes = Integer.parseInt(offlinetime);
		}catch(Exception ignore){}		
		String jsonStr = this.csaMainService.modifyDev(appEui, devEui, offlinetimeMinutes);
		logger.info("moddev2csif: appEui="+appEui+", deveui="+devEui+", ret="+jsonStr);
		ApiResult<MspAck> ret = new ApiResult<MspAck>();		
		ret.setData(this.parseAckJson(jsonStr, "deveui"));
		ret.setRemark("");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	/**
     * CSIF-Dev-Query命令执行.
     * queryDev(String appeui, String deveui) 
     * 
     * appeui: appEUI;
     * deveui: 设备编号. 
	 * 
     * @param request
     * @return 
     * @throws Exception
     */
	@ApiOperation(value = "queryDevFromCSIF", notes = "通过CSIF接口查询DEV（仅限于LNS系统）")
	@RequestMapping(value={"/querydevfromcsif"}, method = RequestMethod.POST)
	@ResponseBody
	public ApiResult<?> querydevfromcsif(HttpServletRequest request) throws Exception{	
		String tokenStr = request.getParameter("token");
		ApiResult<?> ret1 = this.checkToken(tokenStr);
		if(ret1.isRetSucc() == false){
			return ret1;
		}			
		String devEui = request.getParameter("deveui");
		if(devEui == null || devEui.trim().equals("")){
			ret1 = new ApiResult<String>();
			ret1.setRemark("DevEUI parameter is null!");
			ret1.setResult(ApiResult.RET_FAIL);
			return ret1;
		}
		devEui = devEui.trim().toLowerCase();
		String appEui = request.getParameter("appeui");
		if(appEui == null || appEui.trim().equals("")){
			appEui = this.getAppEuiByDevEui(devEui);
		}
		if(appEui == null){
			ret1 = new ApiResult<String>();
			ret1.setRemark("Can't get AppEUI by DevEUI: "+devEui);
			ret1.setResult(ApiResult.RET_FAIL);
			return ret1;
		}
		String jsonStr = this.csaMainService.queryDev(appEui, devEui);
		logger.info("querydevfromcsif: appEui="+appEui+", deveui="+devEui+", ret="+jsonStr);
		ApiResult<DevDataQryAck> ret = new ApiResult<DevDataQryAck>();		
		ret.setData(this.parseCSIFDevQryAckJson(jsonStr));
		ret.setRemark("");
		ret.setResult(ApiResult.RET_SUCC);		
		return ret;
	}
	
	// 根据devEui获取AppEui.
	private String getAppEuiByDevEui(String devEui) throws Exception {
		DevBase dev = this.cacheManager.getDev(devEui);
		if(dev == null){
			return null;
		}
		return dev.getAppEui();
	}
	
	/**
	 * 
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	private MspAck parseAckJson(String jsonStr, String euiName) throws Exception {
		MspAck ack = new MspAck();
		JSONObject json = new JSONObject(jsonStr);
		ack.setEui(XEuiUtils.appendStartZero4xEUI(JsonUtils.getJsonAttrVal(json, euiName, "")));
		ack.setCode(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "code", "0")));
		ack.setMsg(JsonUtils.getJsonAttrVal(json, "msg", ""));
		return ack;
	}
	
	/**
	 * 
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	private DevBuffQryAck parseBuffQryAckJson(String jsonStr) throws Exception {
		DevBuffQryAck ack = new DevBuffQryAck();
		JSONObject json = new JSONObject(jsonStr);
		ack.setEui(XEuiUtils.appendStartZero4xEUI(JsonUtils.getJsonAttrVal(json, "deveui", "")));
		ack.setCode(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "code", "0")));
		ack.setMsg(JsonUtils.getJsonAttrVal(json, "msg", ""));
		ack.setBuff(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "buff", "-1")));
		return ack;
	}
	
	/**
	 * 
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	private DevClazzQryAck parseClassQryAckJson(String jsonStr) throws Exception {
		DevClazzQryAck ack = new DevClazzQryAck();
		JSONObject json = new JSONObject(jsonStr);
		ack.setEui(XEuiUtils.appendStartZero4xEUI(JsonUtils.getJsonAttrVal(json, "deveui", "")));
		ack.setCode(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "code", "0")));
		ack.setMsg(JsonUtils.getJsonAttrVal(json, "msg", ""));
		ack.setClazz(JsonUtils.getJsonAttrVal(json, "class", "A"));
		return ack;
	}	

	/**
	 *  
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	private DevStateQryAck parseDevStateQryAckJson(String jsonStr) throws Exception {
		DevStateQryAck ack = new DevStateQryAck();
		JSONObject json = new JSONObject(jsonStr);
		ack.setEui(XEuiUtils.appendStartZero4xEUI(JsonUtils.getJsonAttrVal(json, "deveui", "")));
		ack.setCode(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "code", "0")));
		// msg字段没有了，这里查询state.
		ack.setMsg(JsonUtils.getJsonAttrVal(json, "state", ""));
		String stateStr = JsonUtils.getJsonAttrVal(json, "state", null);
		if(stateStr != null){
			// 新版本的接口是 state=online|offline
			ack.setOnline("online".equalsIgnoreCase(stateStr.trim()));
		} else {
			// 旧版本的接口是online=true|false
			ack.setOnline(Boolean.parseBoolean(JsonUtils.getJsonAttrVal(json, "online", "false")));
		}
		// 更新本地状态，确保缓存的一致性...
		try{
			DevRunState rs = new DevRunState();
			rs.setDevEUI(ack.getEui());
			byte runState = (ack.isOnline()) ? DevRunState.RUNSTATE_ONLINE : DevRunState.RUNSTATE_OFFLINE;
			rs.setRunState(runState);
			this.persistService.updateDevRunState(rs, true);
		}catch(Exception e){
			logger.error("updateDevRunState failed: "+ack.getEui()+", err="+e.getMessage());
		}
		return ack;
	}
	
	/**
	 * BcastQueQryAck解析
	 * 
	 * @param jsonStr
	 * 		"cmd": "bcastque_ack",
			"cmdseq": 5,
			"castid": 4,
			"key_endbyte": 234,
			"ch": 24,
			"dr": 5,
			"code": 200,
			"msg": "BCAST QUERY SUCC"
	 * @return
	 * @throws Exception
	 */
	private BcastQueQryAck parseBcastQueQryAckJson(String jsonStr) throws Exception {
		BcastQueQryAck ack = new BcastQueQryAck();
		JSONObject json = new JSONObject(jsonStr);
		ack.setEui("NA");
		ack.setCode(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "code", "0")));
		ack.setMsg(JsonUtils.getJsonAttrVal(json, "msg", ""));
		ack.setCastid(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "castid", "0")));
		ack.setKey_endbyte(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "key_endbyte", "0")));
		ack.setCh(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "ch", "0")));
		ack.setDr(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "dr", "0")));
		return ack;
	}
	
	// 解析CSIF-DEV查询响应json
	private DevDataQryAck parseCSIFDevQryAckJson(String jsonStr) throws Exception {
		DevDataQryAck ack = new DevDataQryAck();
		JSONObject json = new JSONObject(jsonStr);		
		ack.setCode(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "code", "500")));
		ack.setEui(XEuiUtils.appendStartZero4xEUI(JsonUtils.getJsonAttrVal(json, "deveui", "")));
		ack.setMsg(JsonUtils.getJsonAttrVal(json, "msg", ""));
		ack.setAppkey(JsonUtils.getJsonAttrVal(json, "appkey", ""));
		ack.setClazz(JsonUtils.getJsonAttrVal(json, "class", ""));
		ack.setOfflinetime(Integer.parseInt(JsonUtils.getJsonAttrVal(json, "offline_time", "0")));
		return ack;
	}
}
